#define _CRT_SECURE_NO_WARNINGS 1

#include "SList.h"

void SLTPrint(SLT* phead)
{
	SLT* cur = phead;
	while (cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

SLT* BuyListNode(SLTDataType x)
{
	SLT* newnode = (SLT*)malloc(sizeof(SLT));
	if (newnode == NULL)
	{
		perror("SLTPushBack::malloc");
		return;
	}
	
	newnode->data = x;
	newnode->next = NULL;

	return newnode;
}

void SLTPushBack(SLT** pphead, SLTDataType x)
{
	assert(pphead);
	SLT* newnode = BuyListNode(x);
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		SLT* cur = *pphead;
		while (cur->next)
		{
			cur = cur->next;
		}
		cur->next = newnode;
	}
}

void SLTPopBack(SLT** pphead)
{
	assert(pphead);
	assert(*pphead);
	SLT* cur = *pphead;
	if (cur->next == NULL)
	{
		*pphead = NULL;
		free(cur);
	}
	else
	{
		SLT* prev = NULL;
		while (cur->next)
		{
			prev = cur;
			cur = cur->next;
		}
		prev->next = cur->next;
		free(cur);
	}
}

void SLTPushFront(SLT** pphead, SLTDataType x)
{
	assert(pphead);
	SLT* newnode = BuyListNode(x);
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		SLT* first = *pphead;
		*pphead = newnode;
		newnode->next = first;
	}
}

void SLTPopFront(SLT** pphead)
{
	assert(pphead);
	assert(*pphead);
	SLT* first = *pphead;
	*pphead = (*pphead)->next;
	free(first);
}

SLT* SLTFind(SLT* plist, SLTDataType x)
{
	assert(plist);
	SLT* cur = plist;
	while (cur)
	{
		if (cur->data != x)
		{
			cur = cur->next;
		}
		else
		{
			return cur;
		}
	}
	return NULL;
}

void SLTInsertAfter(SLT* pos, SLTDataType x)
{
	assert(pos);
	SLT* newnode = BuyListNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

void SLTEraseAfter(SLT* pos)
{
	assert(pos);
	if (pos->next == NULL)
	{
		SLTPopBack(&pos);
	}
	SLT* ref = pos->next;
	pos->next = ref->next;
	free(ref);
}

void SLTInsert(SLT** pphead, SLT* pos, SLTDataType x)
{
	assert(pphead);
	assert(pos);
	SLT* newnode = BuyListNode(x);

	if (pos == *pphead)
	{
		SLTPushFront(pphead, x);
	}
	else
	{
		SLT* cur = *pphead;
		SLT* prev = NULL;
		while (cur != pos)
		{
			prev = cur;
			cur = cur->next;
		}
		prev->next = cur->next;
		free(cur);
	}
}

void SLTErase(SLT** pphead, SLT* pos)
{
	assert(pphead);
	assert(pos);
	SLT* cur = *pphead;
	SLT* prev = NULL;
	while (cur != pos)
	{
		prev = cur;
		cur = cur->next;
	}
	prev->next = cur->next;
	free(cur);
}

void SLTDestroy(SLT** pphead)
{
	assert(pphead);
	free(*pphead);
	*pphead = NULL;
}
